package cn.liumouren.jzxd.service.impl;

import cn.liumouren.jzxd.common.utils.PageUtils;
import cn.liumouren.jzxd.common.utils.Query;
import cn.liumouren.jzxd.dao.PictureDao;
import cn.liumouren.jzxd.dao.SceneDao;
import cn.liumouren.jzxd.dao.SceneZoneDao;
import cn.liumouren.jzxd.dao.TagDao;
import cn.liumouren.jzxd.entity.Scene;
import cn.liumouren.jzxd.entity.Zone;
import cn.liumouren.jzxd.entity.middle.SceneZone;
import cn.liumouren.jzxd.service.SceneService;
import cn.liumouren.jzxd.utils.mapperUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("sceneService")
public class SceneServiceImpl extends ServiceImpl<SceneDao, Scene> implements SceneService {

    @Resource
    private PictureDao pictureDao;
    @Resource
    private SceneDao sceneDao;
    @Resource
    private TagDao tagDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<Scene> page = this.page(
                new Query<Scene>().getPage(params),
                new QueryWrapper<Scene>()
        );
        return new PageUtils(page);
    }

    @Override
    public IPage<Scene> getSceneByTagIds(List<String> tagIds, int cur, int size) {
        if (tagIds == null || tagIds.size() == 0) {
            Page<Scene> page = sceneDao.selectPage(new Page<Scene>(cur, size, false), null);
            List<Scene> records = page.getRecords();
            mapperUtils.getUrlsByEntity(records, pictureDao);
            mapperUtils.getTagsByScenes(records, tagDao);
            page.setRecords(records);
            return page;
//            return null;
        }
        IPage<Scene> page = sceneDao.getSceneByTagIds(new Page<Scene>(cur, size, false), tagIds);
        List<Scene> records = page.getRecords();
        mapperUtils.getUrlsByEntity(records, pictureDao);  // 查询该景点的所有 pic
        mapperUtils.getTagsByScenes(records, tagDao);  // 查询该景点的所有tag
        page.setRecords(records);
        return page;
    }

    @Override
    public IPage<Scene> pageQueryByColumn(Map<String, Integer> map, int cur, int size) {
        // [{'add_time':1},{'hot':0}]
        Integer value;
        String key;
        QueryWrapper<Scene> queryWrapper = new QueryWrapper<>();
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            value = entry.getValue();
            key = entry.getKey();
            if (value == 0) {
                // 0升序
                queryWrapper.orderByAsc(key);
            } else if (value == 1) {
                // 降序
                queryWrapper.orderByDesc(key);
            }
        }
        IPage<Scene> scenePage = baseMapper.selectPage(new Page<Scene>(cur, size, false), queryWrapper);
        List<Scene> records = scenePage.getRecords();
        mapperUtils.getUrlsByEntity(records, pictureDao);
        mapperUtils.getTagsByScenes(records, tagDao);
        scenePage.setRecords(records);
        return scenePage;
    }

    @Override
    public IPage<Scene> queryPageByKey(String key, int cur, int size) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        Page<Scene> page = baseMapper.selectPage(new Page<>(cur, size), new LambdaQueryWrapper<Scene>()
                .like(Scene::getName, key)
                .or()
                .like(Scene::getAddress, key)
                .or()
                .like(Scene::getDescription, key)
                .orderByDesc(Scene::getHot));
        mapperUtils.getUrlsByEntity(page, pictureDao);
        mapperUtils.getTagsByScenes(page, tagDao);
        return page;
    }

    @Override
    public List<Scene> listIdAndName() {
        return baseMapper.selectList(new QueryWrapper<Scene>().lambda().select(Scene::getId, Scene::getName));
    }

    @Override
    public List<Scene> listPageIdAndName(Integer cur, Integer size) {
        return baseMapper.selectList(new QueryWrapper<Scene>().lambda().select(Scene::getId, Scene::getName).last(" limit " + (cur - 1) * size + ", " + size));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(Scene entity) {
        entity.setId(IdWorker.getIdStr());
        entity.setAddTime(new Date());
        mapperUtils.associatePicturesAndEntity(entity, pictureDao);
        return super.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(Scene entity) {
        mapperUtils.associatePicturesAndEntity(entity, pictureDao);
        return SqlHelper.retBool(baseMapper.updateById(entity));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return false;
        }
        return SqlHelper.retBool(baseMapper.deleteBatchIds(idList));
    }

    /**
     * 按照column降序排序
     */
    public List<Scene> orderByColumnDesc(int currentPage, int pageSize, String... columns) {
        List<Scene> scenes = baseMapper.selectList(new QueryWrapper<Scene>()
                .orderByDesc(columns)
                .last(" limit " + (currentPage - 1) * pageSize + "," + pageSize));
        return scenes;
    }

    /**
     * 按照column升序排序
     */
    public List<Scene> orderByColumnAsc(int currentPage, int pageSize, String... columns) {
        List<Scene> scenes = baseMapper.selectList(new QueryWrapper<Scene>()
                .orderByAsc(columns)
                .last(" limit " + (currentPage - 1) * pageSize + "," + pageSize));
        return scenes;
    }

    @Override
    public List<Scene> list() {
        return super.list();
    }

    @Override
    public Scene getById(Serializable id) {
        Scene scene = super.getById(id);
        mapperUtils.getUrlsByEntity(scene, pictureDao);
        mapperUtils.getTagsByScene(scene, tagDao);
        return scene;
    }
}